package cn.edu.gxu.oas.module.run.controller.app.record;

import cn.edu.gxu.oas.framework.common.pojo.CommonResult;
import cn.edu.gxu.oas.framework.common.util.object.BeanUtils;
import cn.edu.gxu.oas.module.member.api.user.MemberUserApi;
import cn.edu.gxu.oas.module.member.api.user.dto.MemberUserRespDTO;
import cn.edu.gxu.oas.module.run.controller.admin.record.vo.RecordSaveReqVO;
import cn.edu.gxu.oas.module.run.controller.app.record.vo.AppLeaderboardItemRespVO;
import cn.edu.gxu.oas.module.run.controller.app.record.vo.AppUserRunStatsRespVO;
import cn.edu.gxu.oas.module.run.dal.dataobject.department.DepartmentDO;
import cn.edu.gxu.oas.module.run.dal.dataobject.record.RecordDO;
import cn.edu.gxu.oas.module.run.service.department.DepartmentService;
import cn.edu.gxu.oas.module.run.service.record.RunRecordService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

import static cn.edu.gxu.oas.framework.common.pojo.CommonResult.success;

/**
 * APP - 跑步记录控制器
 * 提供给前端APP使用的接口
 */
@Tag(name = "APP - 跑步记录")
@RestController
@RequestMapping("/run/record")
@Validated
public class AppRecordController {

    @Resource
    private RunRecordService runRecordService;

    @Resource
    private DepartmentService departmentService;

    @Resource
    private MemberUserApi memberUserApi;

    /**
     * 获取跑步排行榜
     * 统计每个用户的总跑步距离和积分，按积分降序排列
     * 
     * @param limit 返回数量限制，默认为5
     * @return 排行榜数据列表
     */
    @GetMapping("/leaderboard")
    @Operation(summary = "获取跑步排行榜")
    public CommonResult<List<AppLeaderboardItemRespVO>> getLeaderboard(
            @RequestParam(value = "limit", defaultValue = "5") Integer limit) {
        // 1. 获取所有跑步记录
        List<RecordDO> records = runRecordService.getRecordList(null);
        
        // 2. 按学生ID分组并计算总距离和积分
        Map<Long, BigDecimal> studentDistanceMap = new HashMap<>();
        Map<Long, Integer> studentPointsMap = new HashMap<>();
        Set<Long> studentIds = new HashSet<>();
        
        for (RecordDO record : records) {
            Long studentId = record.getStudentId();
            if (studentId == null) {
                continue;
            }
            
            studentIds.add(studentId);
            
            // 累加距离
            BigDecimal currentDistance = studentDistanceMap.getOrDefault(studentId, BigDecimal.ZERO);
            studentDistanceMap.put(studentId, currentDistance.add(record.getDistance()));
            
            // 累加积分
            studentPointsMap.put(
                studentId, 
                studentPointsMap.getOrDefault(studentId, 0) + record.getPoints()
            );
        }
        
        // 3. 获取学生信息
        Map<Long, MemberUserRespDTO> studentMap = memberUserApi.getUserMap(studentIds);
        
        // 4. 获取学院信息
        List<DepartmentDO> departments = departmentService.getDepartmentList(null);
        Map<Long, String> departmentMap = departments.stream()
                .collect(Collectors.toMap(DepartmentDO::getId, DepartmentDO::getName));
        
        // 5. 组装排行榜数据
        List<AppLeaderboardItemRespVO> leaderboard = new ArrayList<>();
        for (Long studentId : studentIds) {
            MemberUserRespDTO student = studentMap.get(studentId);
            if (student == null) {
                continue;
            }
            
            AppLeaderboardItemRespVO item = new AppLeaderboardItemRespVO();
            item.setStudentId(studentId);
            item.setStudentName(student.getNickname());
            item.setAvatar(student.getAvatar());
            
            // 设置学院信息
            Integer deptId = student.getDeptId();
            Long departmentId = deptId != null ? deptId.longValue() : 1L; // 如果没有学院ID，默认使用ID为1的学院
            item.setDepartmentId(departmentId);
            item.setDepartmentName(departmentMap.getOrDefault(departmentId, "未知学院"));
            
            // 设置距离和积分
            item.setTotalDistance(studentDistanceMap.getOrDefault(studentId, BigDecimal.ZERO).doubleValue());
            item.setTotalPoints(studentPointsMap.getOrDefault(studentId, 0));
            
            leaderboard.add(item);
        }
        
        // 6. 按积分排序并限制数量
        leaderboard.sort((a, b) -> b.getTotalPoints().compareTo(a.getTotalPoints()));
        if (leaderboard.size() > limit) {
            leaderboard = leaderboard.subList(0, limit);
        }
        
        return success(leaderboard);
    }

    /**
     * 获取用户跑步统计数据
     * 统计用户的总打卡天数、总跑步距离和总积分
     * 
     * @param userId 用户ID
     * @return 用户跑步统计数据
     */
    @GetMapping("/user-stats")
    @Operation(summary = "获取用户跑步统计数据")
    @Parameter(name = "userId", description = "用户ID", required = true)
    public CommonResult<AppUserRunStatsRespVO> getUserRunStats(@RequestParam("userId") Long userId) {
        // 1. 获取用户的所有跑步记录
        List<RecordDO> records = runRecordService.getRecordListByStudentId(userId);
        
        // 2. 计算统计数据
        AppUserRunStatsRespVO stats = new AppUserRunStatsRespVO();
        stats.setTotalDays((int) records.size());
        
        BigDecimal totalDistance = BigDecimal.ZERO;
        int totalPoints = 0;
        
        for (RecordDO record : records) {
            totalDistance = totalDistance.add(record.getDistance());
            totalPoints += record.getPoints();
        }
        
        stats.setTotalDistance(totalDistance.doubleValue());
        stats.setTotalPoints(totalPoints);
        
        return success(stats);
    }

    /**
     * 检查今日是否已打卡
     * 检查用户在今天是否已经有跑步记录
     * 
     * @param userId 用户ID
     * @return 是否已打卡
     */
    @GetMapping("/check-today")
    @Operation(summary = "检查今日是否已打卡")
    @Parameter(name = "userId", description = "用户ID", required = true)
    public CommonResult<Boolean> checkTodayRunRecord(@RequestParam("userId") Long userId) {
        // 获取今天的开始和结束时间
        LocalDate today = LocalDate.now();
        LocalDateTime startOfDay = today.atStartOfDay();
        LocalDateTime endOfDay = today.atTime(LocalTime.MAX);
        
        // 查询今天的记录
        List<RecordDO> todayRecords = runRecordService.getRecordsByStudentIdAndTimeRange(
                userId, startOfDay, endOfDay);
        
        // 如果有记录，表示今天已打卡
        return success(!todayRecords.isEmpty());
    }

    /**
     * 创建跑步记录
     * 用于用户打卡，记录跑步数据
     * 
     * @param createReqVO 创建跑步记录请求
     * @return 创建的记录ID
     */
    @PostMapping("/create")
    @Operation(summary = "创建跑步记录")
    public CommonResult<Long> createRecord(@Valid @RequestBody RecordSaveReqVO createReqVO) {
        return success(runRecordService.createRecord(createReqVO));
    }
}
